import inspect
import json
import os
import re
import time
import traceback
from typing import Any

from selenium import webdriver
from selenium.webdriver import DesiredCapabilities
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.webdriver import WebDriver

from .autoService_config import *
from .autoService import configInstall,log

# _runDir_ = os.path.split(os.path.realpath(__file__))[0]
configInstall(
    """
# 远程调试浏览器，浏览器需要添加命令 "C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222
DEBUG_SERVER_ADDRESS = "127.0.0.1:9222"

#设置linux下无界面浏览器窗口分辨率
CHROME_WINDOW_SIZE = "1440x900"

""")
# if not os.path.exists(_runDir_ + "/chromeDriver_config.py"):
#     with open(_runDir_ + "/chromeDriver_config.py", "w") as f:
#         f.write(
#             )
from .chromeDriver_config import *

d = DesiredCapabilities.CHROME
d['goog:loggingPrefs'] = {'browser': 'ALL'}


def getDriver():
    if DEBUG == True:
        chrome_options = Options()
        chrome_options.add_experimental_option("debuggerAddress", DEBUG_SERVER_ADDRESS)
        driver = webdriver.Chrome(options=chrome_options, desired_capabilities=d)
    else:
        chrome_options = Options()
        # chrome_options.add_argument("--headless")
        chrome_options.add_argument("--disable-gpu")
        chrome_options.add_argument("headless")
        chrome_options.add_argument("--no-sandbox")
        chrome_options.add_argument("--disable-dev-shm-usage")
        chrome_options.add_argument(f"--window-size={CHROME_WINDOW_SIZE}")
        # chrome_options.headless = True
        driver = webdriver.Chrome(options=chrome_options, desired_capabilities=d)

    return driver


def getAutoSereviceObj(trackId=2) -> Any:
    """
    获取自动化服务对象
    :param trackId:系统工具函数调用请传入 2，外部方法调用请传入 1
    :return:
    """
    caller_frame = sys._getframe(trackId)
    caller_obj = caller_frame.f_locals['self']
    return caller_obj


def getAutoServiceAttr(attrName, trackId=2):
    """
    获取对象某个属性值
    :param attrName: 属性名称
    :param trackId:系统工具函数调用请传入 2，外部方法调用请传入 1
    :return:
    """
    caller_frame = sys._getframe(trackId)
    caller_obj = caller_frame.f_locals['self']
    return getattr(caller_obj, attrName)


def setJqueryAsync():
    """
    设置浏览器里面的jquery请求为同步请求
    :return:
    """
    obj = getAutoServiceAttr("driver")
    obj.execute_script('$.ajaxSettings.async = false;')


def pageReload():
    obj = getAutoServiceAttr("driver")  # type:WebDriver
    obj.refresh()


def getPage(url):
    """
    对应驱动的driver.get方法
    :param url:
    :return:
    """
    obj = getAutoServiceAttr("driver")  # type:WebDriver
    obj.get(url)


def page_wait_done(timeout=5):
    """
    等待页面加载完毕，超时返回假,暂时没多大用

    :param timeout:单位：秒
    :return:
    """

    obj = getAutoServiceAttr("driver")
    start_time = time.time()
    while True:
        v = obj.execute_script('return document.readyState')
        print(v)
        if v == 'complete':
            print("加载耗时:{:.3f}ms".format((time.time() - start_time) * 1000))
            return True
        time.sleep(0.1)
        if time.time() > timeout + start_time:
            # 超时了
            return False


def save_screenshot(suffixName):
    """
    保存浏览器截图
    :param outName:
    :return:
    """
    driver = getAutoServiceAttr('driver')  # type:WebDriver
    getOutFileName = getAutoServiceAttr('getOutFileName')
    driver.save_screenshot(getOutFileName(suffixName))
    # getOutFileName()


def find_element(By, value):
    """
    对饮驱动的driver.find_element
    :param By:
    :param value:
    :return:
    """
    driver = getAutoServiceAttr('driver')
    return driver.find_element(By, value)


# def set_execute_script_pre(script):
#     """
#     设置每条脚本执行前执行一条语句
#     :param script: 比如 a=123;以分号结尾
#     :return:
#     """
#     getAutoSereviceObj()['pre_script']=script#update('pre_script',script)
#     # getAutoServiceAttr('driver')['pre_script'] = script


def execute_script(script: str) -> Any:
    """
    对应驱动的driver.execute_script方法
    :param script:
    :return:
    """
    obj = getAutoServiceAttr("driver")  # type:WebDriver
    # pre_script=getAutoServiceAttr('pre_script')
    # if (type(pre_script) == str):

    log(script.replace("\n",""),model="driver_exec",level="DEBUG")
    return obj.execute_script(script)


def wrap_console_result_to_json(str):
    try:
        return json.loads(eval(f"'{str}'"))
    except:
        return {}


def __default_grepFunc(title: str):
    return True


def get_console_log(grepFunc=__default_grepFunc)->str:
    obj = getAutoServiceAttr("driver")  # type:WebDriver
    match_str = ''
    for t in obj.get_log('browser'):
        if t['level'] == 'INFO' and t['source'] == 'console-api':
            message = t['message']  # type:str
            if not message.startswith('console-api'):
                continue
            data = re.findall("\"(.*)\"", message)
            if data is not None and len(data) > 0:
                m = grepFunc(data[0])
                if m == False or m is None:
                    continue
                else:
                    if type(m) == bool:
                        match_str = data[0]
                    else:
                        match_str = m
    return match_str
